package com.example.nebula.controller;


import com.alibaba.fastjson.JSONObject;
import com.example.nebula.dto.graph.GraphBatchInsertEdge;
import com.example.nebula.dto.graph.GraphDeleteEdge;
import com.example.nebula.dto.graph.GraphInsertEdge;
import com.example.nebula.service.GraphCommonService;
import com.example.nebula.util.NebulaUtil;
import com.example.nebula.util.R;
import com.example.nebula.util.ThreadPoolService;
import com.example.nebula.vo.CommonVo;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * @author fulin
 * @Descriptin: 边控制器
 * @ClassName: VertexController
 */
@RestController
@Api(tags = "边edge管理控制器")
@RequestMapping("/edge")
@Slf4j
public class EdgeManageController {

    @Autowired
    GraphCommonService graphCommonService;

    ListeningExecutorService executorService = MoreExecutors.listeningDecorator(ThreadPoolService.listeningExecutor);

    @PostMapping("/insertEdge")
    @ApiOperation("插入边edge(关系编辑-绑定两个点的关系)")
    public R<List<CommonVo>> insertEdge(@RequestBody GraphInsertEdge graphInsertEdge) {
        String vidType = graphCommonService.getVidType(graphInsertEdge.getSpace());
        return R.data(graphCommonService.executeJson(NebulaUtil.insertEdge(graphInsertEdge,vidType), CommonVo.class));
    }

    @PostMapping("/deleteEdge")
    @ApiOperation("删除边edge(解除关系编辑-解除两个点的关系)")
    public R<List<CommonVo>> deleteEdge(@RequestBody GraphDeleteEdge graphDeleteEdge) {
        String vidType = graphCommonService.getVidType(graphDeleteEdge.getSpace());
        return R.data(graphCommonService.executeJson(NebulaUtil.deleteEdge(graphDeleteEdge,vidType), CommonVo.class));
    }

    @PostMapping("/insertEdges")
    @ApiOperation("插入边edge(关系编辑-绑定两个点的关系)")
    public R<CommonVo> insertEdges(@RequestBody GraphBatchInsertEdge graphBatchInsertEdge)  {
        String vidType = graphCommonService.getVidType(graphBatchInsertEdge.getSpace());

        List<ListenableFuture<CommonVo>> futures = Lists.newArrayList();//监听现场和获取返回值用

        for (GraphInsertEdge graphInsertEdge : graphBatchInsertEdge.getEdges()) {
            graphInsertEdge.setSpace(graphBatchInsertEdge.getSpace());
            Callable<CommonVo> task = new Callable<CommonVo>() {
                @Override
                public CommonVo call() throws Exception {
                    List<CommonVo> result = graphCommonService.executeJson(NebulaUtil.insertEdge(graphInsertEdge, vidType), CommonVo.class);
                    CommonVo vo = result.get(0);
                    vo.setSrcVid(  graphInsertEdge.getSrcVid());
                    vo.setDstVid(  graphInsertEdge.getDstVid());
                    return vo;
                }
            };
            futures.add(executorService.submit(task));
        }
        ListenableFuture<List<CommonVo>> resultsFuture = Futures.successfulAsList(futures);
        List<CommonVo> results = null;
        try {
            results = resultsFuture.get(5, TimeUnit.MINUTES);
        } catch (Exception e) {
            log.error("createVertexs  error, msg [{}]", e.getMessage());
        }

        return R.data(results);
    }


}
